// CXHUDPSock.cpp : implementation file
//

#include "stdafx.h"

#include "XHUDPSock.h"
#include "360RotationDlg.h"

// CXHUDPSock

CXHUDPSock::CXHUDPSock(CDialog* pDlg)
{
	m_pDlg = pDlg;
	m_sendBuffer = "";   //for async send
	m_nBytesSent = 0;
	m_nBytesBufferSize = 0;
}

CXHUDPSock::~CXHUDPSock()
{
}

#if 0
BEGIN_MESSAGE_MAP(CXHUDPSock, CAsyncSocket)
	//{{AFX_MSG_MAP(CXHUDPSock)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0


void CXHUDPSock::OnAccept(int nErrorCode) 
{
	OutputDebugString("CXHUDPSock::OnAccept\n");
	CAsyncSocket::OnAccept(nErrorCode);
}

void CXHUDPSock::OnClose(int nErrorCode) 
{
	OutputDebugString("CXHUDPSock::OnClose\n");
	CAsyncSocket::OnClose(nErrorCode);
	delete this;
}

void CXHUDPSock::OnConnect(int nErrorCode) 
{
	OutputDebugString("CXHUDPSock::OnConnect\n");

	CAsyncSocket::OnConnect(nErrorCode);
}

void CXHUDPSock::OnOutOfBandData(int nErrorCode) 
{
	OutputDebugString("CXHUDPSock::OnOutOfBandData\n");

	CAsyncSocket::OnOutOfBandData(nErrorCode);
}

void CXHUDPSock::OnReceive(int nErrorCode) 
{
	m_receiveBuffer = "";
	OutputDebugString("CXHUDPSock::OnReceive\n");
	TCHAR buff[256];
	memset(buff,0,256);
	int nRead;
	nRead = ReceiveFrom(buff, 255, m_Ip, m_nPort); //make it smaller so we can experiment mulitple notifications
	switch (nRead)
	{
	case 0:
		Close();
		break;
	case SOCKET_ERROR:
		if (GetLastError() != WSAEWOULDBLOCK) 
		{
			if (GetLastError() != WSAEMSGSIZE)
			{
				TCHAR szError[256];
				wsprintf(szError, "OnReceive error: %d\n", GetLastError());
				OutputDebugString(szError);
				return;
			}
			else
			{
				AfxMessageBox ("The datagram was too large and was truncated");
				CString szTemp(buff);
				m_receiveBuffer += szTemp;
			}
		}
		break;

	default:
		if (nRead != SOCKET_ERROR && nRead != 0 )
		{
			TCHAR szError[256];
			wsprintf(szError, "OnReceive bytes: %d", nRead);
			//AfxMessageBox (szError);

			buff[nRead] = 0; //terminate the string
			CString szTemp(buff);
			m_receiveBuffer += szTemp;
		}	
	}

	CAsyncSocket::OnReceive(nErrorCode);
	if (m_Ip == ((CMy360RotationDlg*)m_pDlg)->m_remoteIp && m_nPort == ((CMy360RotationDlg*)m_pDlg)->m_remotePort)
	{
		((CMy360RotationDlg*)m_pDlg)->PauseServiceString(m_receiveBuffer);
	}
	
	else
	{
		char *package = (char *)malloc(nRead+1);
		memcpy(package,buff,nRead+1);
		((CMy360RotationDlg*)m_pDlg)->PausePress(package);
		free(package);
	}

}

void CXHUDPSock::OnSend(int nErrorCode) 
{
	OutputDebugString("CXHUDPSock::OnSend\n");
	DoAsyncSendBuff();	
	CAsyncSocket::OnSend(nErrorCode);
}

int CXHUDPSock::Receive(void* lpBuf, int nBufLen, int nFlags) 
{
	OutputDebugString("CXHUDPSock::Receive\n");
	return CAsyncSocket::Receive(lpBuf, nBufLen, nFlags);
}

int CXHUDPSock::Send(const void* lpBuf, int nBufLen, int nFlags) 
{
	// TODO: Add your specialized code here and/or call the base class
	OutputDebugString("CXHUDPSock::Send\n");

	return CAsyncSocket::Send(lpBuf, nBufLen, nFlags);
}

void CXHUDPSock::DoAsyncSendBuff()
{

	while (m_nBytesSent < m_nBytesBufferSize)  //m_nBytesBufferSize should be m_sendBuffer.GetLength() +1
	{
		int dwBytes;	 
		dwBytes = SendTo((LPCTSTR)m_sendBuffer + m_nBytesSent, m_nBytesBufferSize - m_nBytesSent, 
			m_nPort, (LPCTSTR)m_Ip);

		if (dwBytes == SOCKET_ERROR)
		{
			if (GetLastError() == WSAEWOULDBLOCK) break;
			else
			{
				TCHAR szError[256];
				wsprintf(szError, "Server Socket failed to send: %d\n", GetLastError());
				OutputDebugString(szError);
				return;
			}

		}
		else
		{
			m_nBytesSent += dwBytes;
		}
	}

	if (m_nBytesSent == m_nBytesBufferSize)
	{
		m_nBytesSent = m_nBytesBufferSize = 0;
		m_sendBuffer = "";
	}
}
